const path = require("path");
const fse = require("fs-extra");
const Page = require("../../models/pages");


const dep = async (comm, fun) => {
  if (!Array.isArray(comm) || comm.length === 0) {
    return;
  }
  const promises = comm.map(async (a) => {
    try {
      await fun(a);

      if (a.children && Array.isArray(a.children) && a.children.length > 0) {
        await dep(a.children, fun);
      }
    } catch (error) {
      console.error(`Error processing item ${JSON.stringify(a)}:`, error);
      throw error; // 根据需求决定是否重新抛出错误
    }
  });

  return await Promise.all(promises);
};

// 页面加入到项目
const joinViewsToProject = (
  id,
  projectCode,
  executes,
  modals,
  strcomm,
  url,
  grids
) => {
  return new Promise(async (resolve) => {
    const _Page = await Page.findOne({ _id: id });

    let dir = path.resolve(
      __dirname,
      "../../../projects/" + projectCode + "/src/views" + _Page.url
    );
    if (_Page.url !== url && fse.pathExistsSync(dir)) {
      fse.removeSync(dir);
    }
    dir = path.resolve(
      __dirname,
      "../../../projects/" + projectCode + "/src/views" + url
    );
    const page = path.resolve(__dirname, "../../template/pages/app.vue");
    let str = await fse.readFileSync(page, "utf8");

    let pgf = {};
    strcomm.forEach(async (a) => {
      a = a.comm;
      const s = a.index.split("-");

      let b = JSON.parse(JSON.stringify(a));
      if (s && s.length < 3) {
        const key = b.index.split("-");
        if (!pgf[key[0]]) pgf[key[0]] = [];
        b = Object.assign({}, b, b.attrs);
        const fns = executes.excuteCommApi[b.index];
        if (fns) {
          Object.keys(fns).forEach((k) => {
            b[k] = `func_replace|${fns[k]}`;
          });

          delete b.apiUrl;
        }

        pgf[key[0]] = pgf[key[0]].concat(b);
        delete b.attrs;
        delete b._esr;
      } else {
        const key = a.index.split("-");
        const r = Object.values(pgf).flat();
        const c = r.find((a) => a.index === key[0] + "-" + key[1]);
        if (c && c.children) {
          dep(c.children, (ca) => {
            const fns = executes.excuteCommApi[ca.index];
            if (fns) {
              Object.keys(fns).forEach((k) => {
                ca.attrs.options = `func_replace|${fns[k]}`;
              });
              delete ca.apiUrl;
            }
          });
        }
      }
    });

    const pgfs = JSON.stringify(pgf).replace(
      /\"Filters.list\(\\\"([a-zA-Z0-9-_]+)\\\"\)\"/gim,
      'Filters.list("$1")'
    );

    modals = JSON.stringify(modals).replace(
      /\"Filters.list\(\\\"([a-zA-Z0-9-_]+)\\\"\)\"/gim,
      'Filters.list("$1")'
    );

    str = str.replace(
      /\/\*\{\s?pageConfig\s?\}\*\//gim,
      `const pageConfig = ref(${pgfs})\n`
    );

    str = str.replaceAll(/\"func_replace\|([a-zA-Z0-9-_()]+)\"/g, "$1");

    str = str.replace(
      /\/\*\{\s?modals\s?\}\*\//gim,
      `const modals = ref(${modals})\n`
    );

    str = str.replace(/\/\*\{\s?modals_events\s?\}\*\//gim, executes.modals);

    str = str.replace(
      /\/\*\{\s?layout\s?\}\*\//gim,
      `const layout = ref(${JSON.stringify(grids)})\n`
    );
    str = str.replaceAll(
      /\/\*\{\s?apis\s?\}\*\//gim,
      `${executes.apiUrls.join("\n")}`
    );
    str = str.replaceAll(
      /\/\*\{\s?insert_apis_methods\s?\}\*\//gim,
      `${executes.methods.join("\n")}`
    );
    str = str.replaceAll(
      /\/\*\{\s?execute_apis\s?\}\*\//gim,
      `${executes.executes.join("\n")}`
    );
    str = str.replaceAll(
      /Relace__Events/gim,
      `${executes.emits.cn.join("\n")}`
    );
    str = str.replaceAll(
      /\/\*\{\s?emits_apis\s?\}\*\//gim,
      `${executes.emits.fn.join("\n")}`
    );

    if (!fse.pathExistsSync(dir)) {
      await fse.outputFileSync(dir + "/index.vue", str, "utf8");
    } else {
      const stat = fse.statSync(dir);
      if (stat.isDirectory()) {
        const curl = path.resolve(dir, "index.vue");
        const txt = await fse.readFileSync(curl, "utf8");
        if (txt !== str) {
          await fse.outputFileSync(curl, str, "utf8");
        }
      } else {
        const curl = path.resolve(dir, code + ".vue");
        if (!fse.pathExistsSync(curl)) {
          await fse.outputFileSync(curl, str, "utf8");
        } else {
          const txt = await fse.readFileSync(curl, "utf8");
          if (txt !== str) {
            await fse.outputFileSync(curl, str, "utf8");
          }
        }
      }
    }

    resolve();
  });
};

module.exports = joinViewsToProject;
